/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Portions created by the Initial Developer are
 * Copyright (C) 2012 the Initial Developer.
 * All Rights Reserved.
 *
 * The Original Code is "http://semi-frame.googlecode.com/svn/trenk/".
 *
 * The Initial Developer of the Original Code is the author below.
 */
/**
 * @file NetMessage.cpp
 * @brief auto generated.
 * @author morningcloud
 * @date 2011/03/11
 */

#include "semi/NetMessage.h"

namespace semi {

NetMessage::NetMessage() {
}

//NetMessage::NetMessage(conf::NetConfig::TcpConfig cnf) {
//	this->TaskId = std::string(cnf.task_id);
//	this->port = cnf.serv_port;
//	this->listen = cnf.serv_size;
//
//	std::cout << "NetMessage create instance " << TaskId << " port:" << port
//			<< std::endl;
//}

NetMessage::~NetMessage() {
	//	wait(0);
}

void NetMessage::start(conf::NetConfig::TcpConfig cnf) {

	this->TaskId = std::string(cnf.task_id);
	this->port = cnf.serv_port;
	this->listen = cnf.serv_size;

	if (0 == this->TaskId.length()) {
		std::cout << "NetMessage tcpStart TaskId is empty!" << std::endl;
		return;
	}

	logg::Logger logg = logg::Logger::getLogger(this->TaskId);
	std::stringstream ss;
	ss << "NetMessage receiver of " << this->TaskId << " start! port:"
			<< this->port << " thread:" << getpid();
	logg.info(ss.str());

	CurrentTasks mCrnt(this->TaskId);

	ipc::MessageQue que(this->TaskId);

	util::SocketUtil su(this->port);
	bool bl = su.tcpListen(this->listen);

	while (mCrnt.isValid()) {

		int siz = 0;
		if (0 == cnf.header_size)
			siz = su.tcpReceive(); // wait;
		else
			siz = su.tcpReceive(cnf.header_size, cnf.length_type,
					cnf.length_start); // wait;

		if (siz < 0)
			break;

		su.message;
		// std::cout << "    NetMessage::tcpStart " << msg << std::endl;
		// kick que
		logg.info("NetMessage::send:" + std::string((char*) su.message, siz));
		que.send((char*) su.message, siz);

		sleep(1);
	}
	su.end();

	logg.info("NetMessage receiver of " + this->TaskId + " shutdown!");
}

// static
//void NetMessage::sweep(std::string tskid) {
//
//	conf::NetConfig::TcpConfig cnf = conf::NetConfig().getConfig(tskid);
void NetMessage::sweep(conf::NetConfig::TcpConfig cnf) {
	char m[1];
	m[0] = 0;
	NetMessage::send(cnf, (void*) m, 1);
}

//	static
void NetMessage::send(conf::NetConfig::TcpConfig cnf, std::string message) {
	NetMessage::send(cnf, (void*) message.c_str(), message.length() + 1);
}

//	static
void NetMessage::send(conf::NetConfig::TcpConfig cnf, void* message, int size) {

	std::string taskId = std::string(cnf.task_id);

	if (0 == taskId.length()) {
		std::cout << "NetMessage sweep TaskId is empty!" << std::endl;
		return;
	}

	util::SocketUtil su(std::string(cnf.dist_addr), cnf.dist_port);
	bool bl = su.tcpConnect(5);
	if (bl) {

		if (0 == cnf.header_size) // no header
			bl = su.tcpSend(message, size, 5);
		else {

			if (cnf.header_size < cnf.length_start + cnf.length_type)
				cnf.header_size = cnf.length_start + cnf.length_type;

			void* tmp = malloc(cnf.header_size + size);

			if (2 == cnf.length_type) {
				short s = size;
				memcpy((char*) tmp + cnf.length_start, &s, cnf.length_type);
			} else if (4 == cnf.length_type) {
				long s = size;
				memcpy((char*) tmp + cnf.length_start, &s, cnf.length_type);
			} else if (8 == cnf.length_type) {
				long long s = size;
				memcpy((char*) tmp + cnf.length_start, &s, cnf.length_type);
			} else {
				int s = size;
				cnf.length_type = sizeof(int);
				memcpy((char*) tmp + cnf.length_start, &s, cnf.length_type);
			}

			memcpy((char*) tmp + cnf.header_size, message, size);
			bl = su.tcpSend(tmp, cnf.header_size + size, 5);
		}
		std::cout << "NetMessage sweep send empty message!" << cnf.dist_addr
				<< " " << cnf.dist_port << std::endl;

	} else
		std::cout << "NetMessage sweep fail to connect!" << std::endl;
	su.end();
}

}
